home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MACD 5
/
MACD 5.bin
/
workbench
/
boot
/
czesc_1
/
beep
/
play.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-01-18
|
5KB
|
257 lines
/*
* play.c - routines to load and play an IFF 8SVX sound
*
* Bruno Costa - 19 Feb 91 - 19 Feb 91
*
* (based on ARKM 1.3 example audio2.c)
*/
#include <exec/types.h>
#include <exec/memory.h>
#include <devices/audio.h>
#include <libraries/dos.h>
#include <graphics/gfxbase.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <stdlib.h>
#include <stdio.h>
#include "iff.h"
#define VHDR MakeID('V','H','D','R')
#define BODY MakeID('B','O','D','Y')
#define MY8S MakeID('8','S','V','X')
static struct MsgPort *port; /* audio device port */
static UBYTE *fbuf; /* For sample memory allocation */
static ULONG fsize; /* and freeing */
static Voice8Header *header;
static UBYTE *sample; /* one-shot sample data */
static ULONG length; /* Sample length */
static ULONG clock;
static struct IOAudio *AIOreq;
static int posted = FALSE;
static void setclock (void)
{
struct GfxBase *gbase;
clock = 3579545L; /* NTSC clock */
gbase = (struct GfxBase *) OpenLibrary ("graphics.library", 0L);
if (gbase)
{
if (gbase->DisplayFlags & PAL)
clock = 3546895L; /* PAL clock */
CloseLibrary ((struct Library *) gbase);
}
}
static void abort (void)
{
if (posted && !CheckIO ((struct IORequest *) AIOreq))
AbortIO ((struct IORequest *) AIOreq);
}
static void wait (void)
{
if (posted)
{
WaitPort (port);
(void) GetMsg (port);
posted = FALSE;
}
}
static int sopen (void)
{
static UBYTE chan1[] = { 1 }; /* Audio channel allocation arrays */
static UBYTE chan2[] = { 2 };
static UBYTE chan3[] = { 4 };
static UBYTE chan4[] = { 8 };
static UBYTE *chans[] = {chan1,chan2,chan3,chan4};
ULONG speed = clock / header->samplesPerSec;
AIOreq = (struct IOAudio *) AllocMem (sizeof (*AIOreq), MEMF_PUBLIC | MEMF_CLEAR);
if (AIOreq)
{
port = CreatePort (0, 0);
if (port)
{
int err;
int c = 0; /* start by channel 0 */
do
{
AIOreq->ioa_Request.io_Message.mn_ReplyPort = port;
AIOreq->ioa_Request.io_Message.mn_Node.ln_Pri = 128; /* No stealing! */
AIOreq->ioa_AllocKey = 0;
AIOreq->ioa_Data = chans[c];
AIOreq->ioa_Length = 1;
err = OpenDevice ("audio.device", 0L, (struct IORequest *) AIOreq, 0L);
++c;
} while (err != 0 && c < 4);
if (!err)
{
AIOreq->ioa_Request.io_Command = CMD_WRITE;
AIOreq->ioa_Request.io_Flags = ADIOF_PERVOL;
AIOreq->ioa_Volume = 60;
AIOreq->ioa_Period = (UWORD)speed;
AIOreq->ioa_Cycles = 1;
AIOreq->ioa_Request.io_Message.mn_ReplyPort = port;
AIOreq->ioa_Data = sample;
return TRUE; /* normal return is here */
}
DeletePort (port);
}
FreeMem (AIOreq, sizeof (*AIOreq));
}
return FALSE;
}
static void sclose (void)
{
abort ();
wait ();
CloseDevice ((struct IORequest *) AIOreq);
if (port)
DeletePort (port);
if (AIOreq)
FreeMem (AIOreq, sizeof (*AIOreq));
}
void play (void)
{
abort ();
wait ();
if (length > 0 && length <= 102400)
{
AIOreq->ioa_Length = length;
BeginIO ((struct IORequest *) AIOreq);
posted = TRUE;
}
}
int load (char *fname)
{
UBYTE *data; /* data ptr for file read */
BYTE iobuffer[8]; /* Buffer for 8SVX header */
Chunk *chunk; /* Pointers for 8SVX parsing */
BPTR f;
setclock ();
f = Open (fname, MODE_OLDFILE);
if (f)
{
long count = Read (f, iobuffer, 8L);
if (count == 8)
{
chunk = (Chunk *)iobuffer;
if(chunk->ckID == FORM)
{
fsize = chunk->ckSize;
fbuf = AllocMem (fsize, MEMF_CHIP | MEMF_CLEAR);
if (fbuf)
{
data = fbuf;
count = Read (f, fbuf, chunk->ckSize);
if (count == chunk->ckSize)
{
if (MakeID (*data, *(data+1), *(data+2), *(data+3)) == MY8S)
{
data += 4;
while (data < fbuf + fsize)
{
chunk = (Chunk *)data;
switch (chunk->ckID)
{
case VHDR:
header = (Voice8Header *) (data + 8);
break;
case BODY:
sample = (BYTE *)(data + 8);
length = header->oneShotHiSamples;
if (length == 0)
length = header->repeatHiSamples;
break;
}
data += 8 + chunk->ckSize;
if (chunk->ckSize & 1L == 1)
data++;
}
Close (f);
if (sopen ())
return TRUE; /* normal exit is here */
}
}
FreeMem (fbuf, fsize);
}
}
}
Close (f);
}
return FALSE;
}
void unload (void)
{
sclose ();
if (fbuf)
FreeMem (fbuf, fsize);
fbuf = NULL;
fsize = 0;
}
#ifdef TEST
void main (int argc, char *argv[])
{
if (argc != 2)
{
printf ("usage: %s <sound file>\n", argv[0]);
exit (10);
}
if (load (argv[1]))
{
play ();
wait ();
unload ();
}
}
#endif